﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web.Services.Protocols;
using System.Windows.Forms;
using System.Xml;
using DocumentFormat.OpenXml.Packaging;
using Microsoft.Office.Interop.Word;

namespace TISS_Add_in
{
    public static class AddinUtils
    {
        #region Métodos Privados

        private static X509Certificate2 GetCertificate()
        {
            X509Store certStore = new X509Store(StoreLocation.CurrentUser);
            certStore.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection collection = (X509Certificate2Collection)certStore.Certificates;
            X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, true);
            X509Certificate2Collection certs =
                X509Certificate2UI.SelectFromCollection(collection,
                    "Selecionar um Certificado Digital.",
                    "Por favor selecione um certificado para assinatura.",
                    X509SelectionFlag.SingleSelection);
            return certs.Count > 0 ? certs[0] : null;
        }

        private static void AlteraURLs(URLWebServices URLs)
        {
            if (URLs.URLCancelaGuia != Globals.ThisAddIn.docTISSwsCancelaGuias.Url && !URLs.URLCancelaGuia.Equals(""))
                Globals.ThisAddIn.docTISSwsCancelaGuias.Url = URLs.URLCancelaGuia;

            if (URLs.URLLoteGuias != Globals.ThisAddIn.docTISSwsLoteGuias.Url && !URLs.URLLoteGuias.Equals(""))
                Globals.ThisAddIn.docTISSwsLoteGuias.Url = URLs.URLLoteGuias;

            if (URLs.URLSolicitacaoDemonstrativoRetorno != Globals.ThisAddIn.docTISSwsDemonstrativoRetorno.Url && !URLs.URLSolicitacaoDemonstrativoRetorno.Equals(""))
                Globals.ThisAddIn.docTISSwsDemonstrativoRetorno.Url = URLs.URLSolicitacaoDemonstrativoRetorno;

            if (URLs.URLSolicitacaoProcedimento != Globals.ThisAddIn.docTISSwsSolicitacaoProcedimento.Url && !URLs.URLSolicitacaoProcedimento.Equals(""))
                Globals.ThisAddIn.docTISSwsSolicitacaoProcedimento.Url = URLs.URLSolicitacaoProcedimento;

            if (URLs.URLSolicitacaoStatusProtocolo != Globals.ThisAddIn.docTISSwsStatusProtocolo.Url && !URLs.URLSolicitacaoStatusProtocolo.Equals(""))
                Globals.ThisAddIn.docTISSwsStatusProtocolo.Url = URLs.URLSolicitacaoStatusProtocolo;

            if (URLs.URLSolicitacaoStatusAutorizacao != Globals.ThisAddIn.docTISSwsStatusAutorizacao.Url && !URLs.URLSolicitacaoStatusAutorizacao.Equals(""))
                Globals.ThisAddIn.docTISSwsStatusAutorizacao.Url = URLs.URLSolicitacaoStatusAutorizacao;
        }

        private static void AlteraValorTagCustomXml(XmlDocument xdoc, XmlNamespaceManager nsManager, string xPath, string valor)
        {
            try
            {
                if (valor != null && xPath != null)
                    xdoc.SelectSingleNode(xPath, nsManager).InnerText = valor;
            }
            catch (Exception) { }
        }

        #endregion

        #region Métodos Públicos

        public static string CalculateMD5Hash(string input)
        {
            // step 1, calculate MD5 hash from input
            MD5 md5 = MD5.Create();
            byte[] inputBytes = System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("x2"));
            }
            return sb.ToString().ToUpper();
        }

        public static string CalculateMD5Hash(Stream streamMensagem)
        {
            XmlDocument docMensagem = new XmlDocument();
            docMensagem.Load(streamMensagem);
            string input = "";
            input = docMensagem.DocumentElement.InnerText;

            // step 1, calculate MD5 hash from input
            MD5 md5 = MD5.Create();
            byte[] inputBytes = System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("x2"));
            }
            return sb.ToString().ToUpper();
        }
        /// <summary>
        /// Abre a Guia Selecionada
        /// </summary>
        /// <param name="filePath">Diretório da guia a ser aberta</param>
        public static void AbrirGuia(object filePath)
        {
            try
            {
                object mis = Globals.ThisAddIn._missing;
                object fake = false;
                Globals.ThisAddIn.Application.Documents.Open(ref filePath, ref fake, ref fake, ref mis, ref mis,
                                                            ref mis, ref mis, ref mis, ref mis, ref mis, ref mis,
                                                            ref mis, ref mis, ref mis, ref mis, ref mis);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            if (Globals.ThisAddIn.AcompanhaGuiaCTP != null)
                if (!Globals.ThisAddIn.AcompanhaGuiaCTP.Visible)
                    Globals.Ribbons.Ribbon1.btnAcompanhar.Checked = Globals.ThisAddIn.AcompanhaGuiaCTP.Visible;
        }
        /// <summary>
        /// Fecha a Guia Selecionada
        /// </summary>
        /// <param name="filePath">Diretório da guia a ser fechada</param>
        public static void FecharGuia(object filePath)
        {
            try
            {
                object mis = Globals.ThisAddIn._missing;
                object promptToSaveChanges = WdSaveOptions.wdPromptToSaveChanges;
                DocumentClass doc = Globals.ThisAddIn.Application.Documents.get_Item(ref filePath) as DocumentClass;
                doc.Close(ref promptToSaveChanges, ref mis, ref mis);
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Mostra as Mensagens de Erro do WebService
        /// </summary>
        /// <param name="spEx">SoapException do WS</param>
        public static void ShowErrorMessageWS(SoapException spEx)
        {
            try
            {
                switch (spEx.Detail.FirstChild.Name)
                {
                    case "DestinatarioInvalido":
                        MessageBox.Show("Mensagem não enviada.\nO WebService da operadora retornou um erro: Destinatário Inválido.", "Destinatário inválido!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                        break;
                    case "RemetenteInvalido":
                        MessageBox.Show("Mensagem não enviada.\nO WebService da operadora retornou um erro: Remetente Inválido.", "Remetente inválido!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                        break;
                    case "VersaoInvalida":
                        MessageBox.Show("Mensagem não enviada.\nO WebService da operadora retornou um erro: Versão Inválida.", "Versão inválida!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                        break;
                    case "HashInvalido":
                        MessageBox.Show("Mensagem não enviada.\nO WebService da operadora retornou um erro: Hash Inválido.", "Hash inválido!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                        break;
                }
            }
            catch
            {
                MessageBox.Show("Mensagem não enviada.\nO WebService da operadora retornou um erro de processamento.", "Mensagem não enviada.", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
            }
        }

        public static string DescricaoStatus(st_statusSolicitacao descStatus)
        {
            string Status = "";
            switch (descStatus)
            {
                case st_statusSolicitacao.Item1:
                    Status = "Autorizado";
                    break;
                case st_statusSolicitacao.Item2:
                    Status = "Em análise";
                    break;
                case st_statusSolicitacao.Item3:
                    Status = "Negado";
                    break;
            }
            return Status;
        }

        public static bool ConfiguraConexao(URLWebServices URLs)
        {
            X509Certificate2 cert = GetCertificate();
            if (cert != null)
            {
                System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();

                Globals.ThisAddIn.docTISSwsCancelaGuias.ClientCertificates.Add(cert);
                Globals.ThisAddIn.docTISSwsLoteGuias.ClientCertificates.Add(cert);
                Globals.ThisAddIn.docTISSwsDemonstrativoRetorno.ClientCertificates.Add(cert);
                Globals.ThisAddIn.docTISSwsSolicitacaoProcedimento.ClientCertificates.Add(cert);
                Globals.ThisAddIn.docTISSwsStatusProtocolo.ClientCertificates.Add(cert);
                Globals.ThisAddIn.docTISSwsStatusAutorizacao.ClientCertificates.Add(cert);

                AlteraURLs(URLs);

                return true;
            }
            return false;
        }

        public static void PreencheGuia(string pathGuia, DadosAutoPreencherGuia dadosAutoPreencher, TipoProfissional tipoProfissional)
        {
            XmlDocument xdoc = new XmlDocument();
            XmlDocument xmlMainDoc = new XmlDocument();

            using (WordprocessingDocument wdoc = WordprocessingDocument.Open(pathGuia, false))
            {
                xmlMainDoc.Load(wdoc.MainDocumentPart.GetStream());

                //Buscando o CustomXML referente a Guia
                foreach (CustomXmlPart cPart in wdoc.MainDocumentPart.CustomXmlParts)
                {
                    //Carrega a parte
                    xdoc.Load(cPart.GetStream());

                    //Encontrou?
                    if (xdoc.InnerXml.Contains("ans"))
                    {
                        XmlNamespaceManager nsManager = new XmlNamespaceManager(xdoc.NameTable);
                        nsManager.AddNamespace("ans", "http://www.ans.gov.br/padroes/tiss/schemas");
                        nsManager.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");

                        string xPathCodigoPrestador = null;

                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.RegistroANS, dadosAutoPreencher.dadosGuia.RegistroANS);
                        switch (tipoProfissional)
                        {
                            case TipoProfissional.ProfissionalSolicitanteExecutante:
                            case TipoProfissional.ProfissionalSolicitante:
                                xPathCodigoPrestador = XMLUtils.BuscaXPathCodigoPrestadorExistente(dadosAutoPreencher.xPathSolicitante, xdoc, nsManager);
                                if (xPathCodigoPrestador != null)
                                {
                                    if (dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora != null && !dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora.Equals(""))
                                    {
                                        XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "codigoPrestadorNaOperadora");
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CodigoPrestadorNaOperadora, dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora);
                                        xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CodigoPrestadorNaOperadora, TipoProfissional.ProfissionalSolicitante);
                                    }
                                    else
                                    {
                                        if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 11)
                                        {
                                            XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "CPF");
                                            AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CPF, dadosAutoPreencher.dadosGuia.CPF_CNPJ);
                                            xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CPF, TipoProfissional.ProfissionalSolicitante);
                                        }
                                        else if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 14)
                                        {
                                            XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "CNPJ");
                                            AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CNPJ, dadosAutoPreencher.dadosGuia.CPF_CNPJ);
                                            xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CNPJ, TipoProfissional.ProfissionalSolicitante);
                                        }
                                    }
                                }
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.NomeContratado, dadosAutoPreencher.dadosGuia.NomeContratado);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.TipoLogradouro, dadosAutoPreencher.dadosGuia.TipoLogradouro);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.Logradouro, dadosAutoPreencher.dadosGuia.Logradouro);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.Numero, dadosAutoPreencher.dadosGuia.Numero);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.Complemento, dadosAutoPreencher.dadosGuia.Complemento);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CodigoIBGEMunicipio, dadosAutoPreencher.dadosGuia.CodigoIBGEMunicipio);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.Municipio, dadosAutoPreencher.dadosGuia.Municipio);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CodigoUF, dadosAutoPreencher.dadosGuia.CodigoUF);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.Cep, dadosAutoPreencher.dadosGuia.Cep);
                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CNES, dadosAutoPreencher.dadosGuia.CNES);
                                if (dadosAutoPreencher.tipoGuia == TipoGuia.SP_SADT || dadosAutoPreencher.tipoGuia == TipoGuia.SP_SADT_Reapresentação)
                                {
                                    if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 11)
                                    {
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.SiglaConselho, dadosAutoPreencher.dadosGuia.SiglaConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.NumeroConselho, dadosAutoPreencher.dadosGuia.NumeroConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.UFConselho, dadosAutoPreencher.dadosGuia.UFConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathSolicitante.CBOS, dadosAutoPreencher.dadosGuia.CBOS);
                                    }
                                }
                                if (tipoProfissional == TipoProfissional.ProfissionalSolicitanteExecutante)
                                    goto case TipoProfissional.ProfissionalExecutante;
                                break;
                            case TipoProfissional.ProfissionalExecutante:
                                if (dadosAutoPreencher.tipoGuia != TipoGuia.Consulta && dadosAutoPreencher.tipoGuia != TipoGuia.Consulta_Reapresentação)
                                {
                                    xPathCodigoPrestador = XMLUtils.BuscaXPathCodigoPrestadorExistente(dadosAutoPreencher.xPathExecutante, xdoc, nsManager);
                                    if (xPathCodigoPrestador != null)
                                    {
                                        if (dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora != null && !dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora.Equals(""))
                                        {
                                            XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "codigoPrestadorNaOperadora");
                                            AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CodigoPrestadorNaOperadora, dadosAutoPreencher.dadosGuia.CodigoPrestadorNaOperadora);
                                            xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CodigoPrestadorNaOperadora, TipoProfissional.ProfissionalExecutante);
                                        }
                                        else
                                        {
                                            if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 11)
                                            {
                                                XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "CPF");
                                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CPF, dadosAutoPreencher.dadosGuia.CPF_CNPJ);
                                                xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CPF, TipoProfissional.ProfissionalExecutante);
                                            }
                                            else if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 14)
                                            {
                                                XMLUtils.RenameNode(xdoc.SelectSingleNode(xPathCodigoPrestador, nsManager), "CNPJ");
                                                AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CNPJ, dadosAutoPreencher.dadosGuia.CPF_CNPJ);
                                                xmlMainDoc = XMLUtils.SubstituiCustomControlXmlMapping(dadosAutoPreencher.tipoGuia, xmlMainDoc, TipoCustomControlXmlMapping.CNPJ, TipoProfissional.ProfissionalExecutante);
                                            }
                                        }
                                    }
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.NomeContratado, dadosAutoPreencher.dadosGuia.NomeContratado);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.TipoLogradouro, dadosAutoPreencher.dadosGuia.TipoLogradouro);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.Logradouro, dadosAutoPreencher.dadosGuia.Logradouro);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.Numero, dadosAutoPreencher.dadosGuia.Numero);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.Complemento, dadosAutoPreencher.dadosGuia.Complemento);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CodigoIBGEMunicipio, dadosAutoPreencher.dadosGuia.CodigoIBGEMunicipio);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.Municipio, dadosAutoPreencher.dadosGuia.Municipio);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CodigoUF, dadosAutoPreencher.dadosGuia.CodigoUF);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.Cep, dadosAutoPreencher.dadosGuia.Cep);
                                    AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CNES, dadosAutoPreencher.dadosGuia.CNES);
                                    if (dadosAutoPreencher.dadosGuia.CPF_CNPJ.Length == 11)
                                    {
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.NomeProfissional, dadosAutoPreencher.dadosGuia.NomeContratado);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.SiglaConselho, dadosAutoPreencher.dadosGuia.SiglaConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.NumeroConselho, dadosAutoPreencher.dadosGuia.NumeroConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.UFConselho, dadosAutoPreencher.dadosGuia.UFConselho);
                                        AlteraValorTagCustomXml(xdoc, nsManager, dadosAutoPreencher.xPathExecutante.CBOS, dadosAutoPreencher.dadosGuia.CBOS);
                                    }
                                }
                                break;
                            default:
                                break;
                        }
                        break;
                    }
                }
            }
            XMLUtils.SubstituiCustomXmlPart(pathGuia, "ans:registroANS", xdoc);
            XMLUtils.SubstituiMainDocumentPart(pathGuia, xmlMainDoc);
        }

        public static void AlteraLogoGuia(Image logotipo)
        {
            object mis = Globals.ThisAddIn._missing;
            object logoOperadoraCC = 1;
            if (logotipo != null)
            {
                string pathLogo = Path.GetTempFileName() + ".png";
                logotipo.Save(pathLogo, ImageFormat.Png);

                Globals.ThisAddIn.doc.ContentControls.get_Item(ref logoOperadoraCC).Range.InlineShapes.AddPicture(pathLogo, ref mis, ref mis, ref mis);
                Globals.ThisAddIn.IndexNumeroGuiaCC = 2;
            }
            else
            {
                Globals.ThisAddIn.doc.ContentControls.get_Item(ref logoOperadoraCC).Delete(true);
                Globals.ThisAddIn.IndexNumeroGuiaCC = 1;
            }
        }

        public static void AddContentControlToRange(Microsoft.Office.Interop.Word.Range range, string nodeXPath, Microsoft.Office.Core.CustomXMLPart customXMLPart)
        {
            object refCCRange = range;
            range.Select();
            Microsoft.Office.Interop.Word.ContentControl cc = range.ContentControls.Add(Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlText, ref refCCRange);
            cc.SetPlaceholderText(null, null, "Editar");
            Microsoft.Office.Core.CustomXMLNode nodeMapping = customXMLPart.DocumentElement.SelectSingleNode(nodeXPath);

            cc.XMLMapping.SetMappingByNode(nodeMapping);
        }

        public static void AddContentControlToRange(Microsoft.Office.Interop.Word.ContentControl oldCC, Microsoft.Office.Interop.Word.Range range, string nodeXPath, Microsoft.Office.Core.CustomXMLPart customXMLPart)
        {
            object refCCRange = range;
            range.Select();
            Microsoft.Office.Interop.Word.ContentControl cc = range.ContentControls.Add(oldCC.Type, ref refCCRange);//ref Globals.ThisAddIn._missing);

            if (cc.Type == WdContentControlType.wdContentControlDropdownList)
            {
                foreach (ContentControlListEntry item in oldCC.DropdownListEntries)
                {
                    cc.DropdownListEntries.Add(item.Text, item.Value, item.Index);
                }
            }
            else if (cc.Type == WdContentControlType.wdContentControlDate)
            {
                cc.DateStorageFormat = oldCC.DateStorageFormat;
                cc.DateDisplayLocale = oldCC.DateDisplayLocale;
                cc.DateDisplayFormat = oldCC.DateDisplayFormat;
                cc.DateCalendarType = oldCC.DateCalendarType;
            }
            cc.SetPlaceholderText(null, null, "Editar");

            Microsoft.Office.Core.CustomXMLNode nodeMapping = customXMLPart.DocumentElement.SelectSingleNode(nodeXPath);
            cc.XMLMapping.SetMappingByNode(nodeMapping);
        }
        #endregion
    }

    public class DataOfAvailableRow
    {
        private Microsoft.Office.Interop.Word.Row row;
        private int rowIndexToSkip;
        private int numberOfTable;
        private int rowIndex;
        private bool isNewRow = false;

        #region Properties
        public Microsoft.Office.Interop.Word.Row Row
        {
            get { return row; }
            set 
            {
                rowIndex = value.Index;
                row = value;
            }
        }
        
        public int RowIndexToSkip
        {
            get { return rowIndexToSkip; }
            set { rowIndexToSkip = value; }
        }
        

        public int NumberOfTable
        {
            get { return numberOfTable; }
            set { numberOfTable = value; }
        }
        

        public int RowIndex
        {
            get { return rowIndex; }
            set { rowIndex = value; }
        }

        public bool IsNewRow
        {
            get { return isNewRow; }
            set { isNewRow = value; }
        }
        #endregion

        public DataOfAvailableRow()
        { }

        public DataOfAvailableRow(Microsoft.Office.Interop.Word.Row row)
        {
            this.row = row;
            this.numberOfTable = 1;
        }

        public DataOfAvailableRow(Microsoft.Office.Interop.Word.Row row, int rowIndexToSkip)
        { 
            this.row = row;
            this.rowIndexToSkip = rowIndexToSkip;
            this.numberOfTable = 1;
        }

        public DataOfAvailableRow(Microsoft.Office.Interop.Word.Row row, int rowIndexToSkip, int numberOfTable)
        {
            this.row = row;
            this.rowIndexToSkip = rowIndexToSkip;
            this.numberOfTable = numberOfTable;
        }

        public DataOfAvailableRow(Microsoft.Office.Interop.Word.Row row, int rowIndexToSkip, int numberOfTable, int rowIndex)
        {
            this.row = row;
            this.rowIndexToSkip = rowIndexToSkip;
            this.numberOfTable = numberOfTable;
            this.rowIndex = rowIndex;
        }

        public static DataOfAvailableRow GetNextAvailableRow(DataOfAvailableRow infoRow, string textToAddRow)
        {
            if (infoRow.Row.Range.ContentControls.Count == 0)
            {
                if (infoRow.Row.Next.Range.Text.Contains(textToAddRow) || infoRow.Row.Next == null)
                {
                    infoRow.IsNewRow = true;
                    object addBeforeRow = infoRow.Row;
                    Globals.ThisAddIn.Application.ActiveDocument.Tables[infoRow.NumberOfTable].Rows.Add(ref addBeforeRow);
                    Globals.ThisAddIn.Application.ActiveDocument.Tables[infoRow.NumberOfTable].Rows[infoRow.RowIndex].Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].Visible = false;
                    infoRow.Row = Globals.ThisAddIn.Application.ActiveDocument.Tables[infoRow.NumberOfTable].Rows[infoRow.RowIndex];
                }
                return infoRow;
            }

            infoRow.Row = infoRow.Row.Next;
            return GetNextAvailableRow(infoRow, textToAddRow);
        }

        public static DataOfAvailableRow GetNextAvailableRow(DataOfAvailableRow infoRow, string textToNextTable, string textToAddRow)
        {
            if (infoRow.Row.Index >= infoRow.RowIndexToSkip)
            {
                infoRow.NumberOfTable++;

                foreach (Microsoft.Office.Interop.Word.Row tableRow in Globals.ThisAddIn.Application.ActiveDocument.Tables[infoRow.NumberOfTable].Rows)
                {
                    if (tableRow.Range.Text.Contains(textToNextTable))
                    {
                        infoRow.Row = tableRow.Next.Next;
                        break;
                    }
                }
                return GetNextAvailableRow(infoRow, textToAddRow);
            }

            if ((infoRow.Row.Range.ContentControls.Count == 0))
            {
                infoRow.RowIndex = infoRow.Row.Index;
                return infoRow;
            }

            infoRow.Row = infoRow.Row.Next;
            return GetNextAvailableRow(infoRow, textToNextTable, textToAddRow);
        }
    }

    public class Validacoes
    {
        public static bool ValidaCPF(string vrCPF)
        {
            string valor = vrCPF.Replace(".", "");
            valor = valor.Replace("-", "");
            if (valor.Length != 11)
                return false;
            bool igual = true;
            for (int i = 1; i < 11 && igual; i++)
                if (valor[i] != valor[0])
                    igual = false;
            if (igual || valor == "12345678909")
                return false;
            int[] numeros = new int[11];
            for (int i = 0; i < 11; i++)
                numeros[i] = int.Parse(
                  valor[i].ToString());
            int soma = 0;
            for (int i = 0; i < 9; i++)
                soma += (10 - i) * numeros[i];
            int resultado = soma % 11;
            if (resultado == 1 || resultado == 0)
            {
                if (numeros[9] != 0)
                    return false;
            }
            else if (numeros[9] != 11 - resultado)
                return false;
            soma = 0;
            for (int i = 0; i < 10; i++)
                soma += (11 - i) * numeros[i];
            resultado = soma % 11;
            if (resultado == 1 || resultado == 0)
            {
                if (numeros[10] != 0)
                    return false;
            }
            else
                if (numeros[10] != 11 - resultado)
                    return false;
            return true;
        }

        public static bool ValidaCNPJ(string vrCNPJ)
        {
            string CNPJ = vrCNPJ.Replace(".", "");
            CNPJ = CNPJ.Replace("/", "");
            CNPJ = CNPJ.Replace("-", "");
            int[] digitos, soma, resultado;
            int nrDig;
            string ftmt;
            bool[] CNPJOk;
            ftmt = "6543298765432";
            digitos = new int[14];
            soma = new int[2];
            soma[0] = 0;
            soma[1] = 0;
            resultado = new int[2];
            resultado[0] = 0;
            resultado[1] = 0;
            CNPJOk = new bool[2];
            CNPJOk[0] = false;
            CNPJOk[1] = false;
            try
            {
                for (nrDig = 0; nrDig < 14; nrDig++)
                {
                    digitos[nrDig] = int.Parse(
                        CNPJ.Substring(nrDig, 1));
                    if (nrDig <= 11)
                        soma[0] += (digitos[nrDig] *
                          int.Parse(ftmt.Substring(
                          nrDig + 1, 1)));
                    if (nrDig <= 12)
                        soma[1] += (digitos[nrDig] *
                          int.Parse(ftmt.Substring(
                          nrDig, 1)));
                }
                for (nrDig = 0; nrDig < 2; nrDig++)
                {
                    resultado[nrDig] = (soma[nrDig] % 11);
                    if ((resultado[nrDig] == 0) || (
                         resultado[nrDig] == 1))
                        CNPJOk[nrDig] = (
                        digitos[12 + nrDig] == 0);
                    else
                        CNPJOk[nrDig] = (
                        digitos[12 + nrDig] == (
                        11 - resultado[nrDig]));
                }
                return (CNPJOk[0] && CNPJOk[1]);
            }
            catch
            {
                return false;
            }
        }
    }

    public class URLWebServices
    {
        public string URLCancelaGuia = null;
        public string URLLoteGuias = null;
        public string URLSolicitacaoDemonstrativoRetorno = null;
        public string URLSolicitacaoProcedimento = null;
        public string URLSolicitacaoStatusProtocolo = null;
        public string URLSolicitacaoStatusAutorizacao = null;
    }

    public class TreeNodeContents
    {
        public node_type tipo_node;
        public string regANS = null;
        public TipoGuia tipo_guia;
        public long? lote_cod = null;
        public long? sequencial_transacao = null;
        public string protocolo = null;
        public string numeroGuia = null;
        public string numeroGuiaOperadora = null;
        public string guia_path = null;
        public string guia_data_emissao = null;
        public long? guiaID = null;
        public URLWebServices URLs = new URLWebServices();

        public TreeNodeContents()
        {
        }

        /// <summary>
        /// Operadora
        /// </summary>
        /// <param name="regANS"></param>
        public TreeNodeContents(string regANS, URLWebServices urls)
            : this()
        {
            this.regANS = regANS;
            this.tipo_node = node_type.operadora;
            this.URLs = urls;
        }

        /// <summary>
        /// Tipo de Guia
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="urls"></param>
        public TreeNodeContents(string regANS, TipoGuia tipoGuia, URLWebServices urls)
            : this(regANS, urls)
        {
            this.tipo_guia = tipoGuia;
            if (tipoGuia <= TipoGuia.Odontologia_Reapresentação)
                this.tipo_node = node_type.tipo_lote;
            else
                this.tipo_node = node_type.tipo_solicitacao;
        }

        #region Não Enviado

        /// <summary>
        /// Lote não enviado
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="cod_lote"></param>
        public TreeNodeContents(string regANS, TipoGuia tipoGuia, long? cod_lote, URLWebServices urls)
            : this(regANS, tipoGuia, urls)
        {
            this.lote_cod = cod_lote;
            this.tipo_node = node_type.lote;
        }

        /// <summary>
        /// Guia Faturamento Não enviada
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="cod_lote"></param>
        /// <param name="numeroGuia"></param>
        /// <param name="path_guia"></param>
        /// <param name="data_emissao_guia"></param>
        /// <param name="tipoGuia"></param>
        public TreeNodeContents(string regANS, TipoGuia tipoGuia, long? cod_lote,
            string numeroGuia, string path_guia, string data_emissao_guia, URLWebServices urls)
            : this(regANS, tipoGuia, cod_lote, urls)
        {
            this.numeroGuia = numeroGuia;
            this.guia_path = path_guia;
            this.guia_data_emissao = data_emissao_guia;
            this.tipo_node = node_type.guiaFaturamento;
        }

        /// <summary>
        /// Guia Solicitação Não Enviada
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="numeroGuia"></param>
        /// <param name="path_guia"></param>
        /// <param name="data_emissao_guia"></param>
        /// <param name="urls"></param>
        public TreeNodeContents(string regANS, TipoGuia tipoGuia,
            string numeroGuia, string path_guia, string data_emissao_guia, URLWebServices urls)
            : this(regANS, tipoGuia, urls)
        {
            this.numeroGuia = numeroGuia;
            this.guia_path = path_guia;
            this.guia_data_emissao = data_emissao_guia;
            this.tipo_node = node_type.guiaSolicitacao;
        }

        /// <summary>
        /// guia extensão não enviada
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="cod_lote"></param>
        /// <param name="numeroGuia"></param>
        /// <param name="path_guia"></param>
        /// <param name="data_emissao_guia"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="guiaID"></param>
        public TreeNodeContents(string regANS, TipoGuia tipoGuia,
            string numeroGuia, string path_guia, string data_emissao_guia, long? guiaID)
            : this(regANS, tipoGuia, null)
        {
            this.numeroGuia = numeroGuia;
            this.guia_path = path_guia;
            this.guia_data_emissao = data_emissao_guia;
            this.tipo_node = node_type.guiaExtensao;
            this.guiaID = guiaID;
        }

        #endregion

        #region Enviado

        /// <summary>
        /// Lote Enviado
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="cod_lote"></param>
        /// <param name="sequencial_transacao"></param>
        /// <param name="protocolo"></param>
        public TreeNodeContents(string regANS, TipoGuia tipoGuia, long? cod_lote,
            long? sequencial_transacao, string protocolo, URLWebServices urls)
            : this(regANS, tipoGuia, urls)
        {
            this.lote_cod = cod_lote;
            this.sequencial_transacao = sequencial_transacao;
            this.protocolo = protocolo;
            this.tipo_node = node_type.lote;
        }

        /// <summary>
        /// Guia Faturamento Enviada
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="cod_lote"></param>
        /// <param name="sequencial_transacao"></param>
        /// <param name="protocolo"></param>
        /// <param name="numeroGuia"></param>
        /// <param name="numeroGuiaOperadora"></param>
        /// <param name="path_guia"></param>
        /// <param name="data_emissao_guia"></param>
        /// <param name="tipoGuia"></param>
        public TreeNodeContents(string regANS, TipoGuia tipoGuia, long? cod_lote,
            long? sequencial_transacao, string protocolo, string numeroGuia, string numeroGuiaOperadora,
            string path_guia, string data_emissao_guia, URLWebServices urls)
            : this(regANS, tipoGuia, cod_lote, sequencial_transacao, protocolo, urls)
        {
            this.numeroGuia = numeroGuia;
            this.numeroGuiaOperadora = numeroGuiaOperadora;
            this.guia_path = path_guia;
            this.guia_data_emissao = data_emissao_guia;
            this.tipo_node = node_type.guiaFaturamento;
        }

        /// <summary>
        /// Guia Solicitação Enviada
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="cod_lote"></param>
        /// <param name="sequencial_transacao"></param>
        /// <param name="protocolo"></param>
        /// <param name="numeroGuia"></param>
        /// <param name="numeroGuiaOperadora"></param>
        /// <param name="path_guia"></param>
        /// <param name="data_emissao_guia"></param>
        /// <param name="urls"></param>
        public TreeNodeContents(string regANS, TipoGuia tipoGuia,
            long? sequencial_transacao, string numeroGuia, string numeroGuiaOperadora,
            string path_guia, string data_emissao_guia, URLWebServices urls)
            : this(regANS, tipoGuia, null, sequencial_transacao, null, urls)
        {
            this.numeroGuia = numeroGuia;
            this.numeroGuiaOperadora = numeroGuiaOperadora;
            this.guia_path = path_guia;
            this.guia_data_emissao = data_emissao_guia;
            this.tipo_node = node_type.guiaSolicitacao;
        }

        /// <summary>
        /// guia extensão enviada
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="cod_lote"></param>
        /// <param name="sequencial_transacao"></param>
        /// <param name="protocolo"></param>
        /// <param name="numeroGuia"></param>
        /// <param name="numeroGuiaOperadora"></param>
        /// <param name="path_guia"></param>
        /// <param name="data_emissao_guia"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="guiaID"></param>
        public TreeNodeContents(string regANS, TipoGuia tipoGuia,
            long? sequencial_transacao, string protocolo, string numeroGuia, string numeroGuiaOperadora,
            string path_guia, string data_emissao_guia, long? guiaID)
            : this(regANS, tipoGuia, null, sequencial_transacao, protocolo, null)
        {
            this.numeroGuia = numeroGuia;
            this.numeroGuiaOperadora = numeroGuiaOperadora;
            this.guia_path = path_guia;
            this.guia_data_emissao = data_emissao_guia;
            this.tipo_node = node_type.guiaExtensao;
            this.guiaID = guiaID;
        }

        #endregion
    }

    public class TreeNodeContentsDemonstrativo
    {
        public node_type tipo_node = new node_type();
        public string regANS = null;
        public URLWebServices URLs = new URLWebServices();

        public TipoGuia tipoGuia = new TipoGuia();

        public long? loteCod = null;
        public long? sequencialTransacao = null;
        public long? protocoloRecebimento = null;
        public long? demonstrativoCod = null;

        public string numeroGuiaPrestador = null;
        public string numeroGuiaOperadora = null;
        //public string guiaPath = null;
        public string dataEmissao = null;

        public TreeNodeContentsDemonstrativo()
        {
        }
        /// <summary>
        /// node_type.operadora
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="URLs"></param>
        public TreeNodeContentsDemonstrativo(string regANS, URLWebServices URLs)
        {
            this.tipo_node = node_type.operadora;

            this.regANS = regANS;
            this.URLs = URLs;
        }
        /// <summary>
        /// node_type.tipo_lote
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="URLs"></param>
        /// <param name="tipoGuia"></param>
        public TreeNodeContentsDemonstrativo(string regANS, URLWebServices URLs,
            TipoGuia tipoGuia)
            : this(regANS, URLs)
        {
            this.tipo_node = node_type.tipo_lote;

            this.tipoGuia = tipoGuia;
        }
        /// <summary>
        /// node_type.lote
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="URLs"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="loteCod"></param>
        /// <param name="sequencialTransacao"></param>
        /// <param name="protocoloRecebimento"></param>
        public TreeNodeContentsDemonstrativo(string regANS, URLWebServices URLs,
            TipoGuia tipoGuia,
            long loteCod, long sequencialTransacao, long protocoloRecebimento, long? demonstrativoCod)
            : this(regANS, URLs, tipoGuia)
        {
            this.tipo_node = node_type.lote;

            this.loteCod = loteCod;
            this.sequencialTransacao = sequencialTransacao;
            this.protocoloRecebimento = protocoloRecebimento;
            this.demonstrativoCod = demonstrativoCod;
        }
        /// <summary>
        /// node_type.guiaSolicitacao
        /// </summary>
        /// <param name="regANS"></param>
        /// <param name="URLs"></param>
        /// <param name="tipoGuia"></param>
        /// <param name="loteCod"></param>
        /// <param name="sequencialTransacao"></param>
        /// <param name="protocoloRecebimento"></param>
        /// <param name="guiaCod"></param>
        /// <param name="numeroGuiaPrestador"></param>
        /// <param name="numeroGuiaOperadora"></param>
        /// <param name="guiaPath"></param>
        /// <param name="dataEmissao"></param>
        public TreeNodeContentsDemonstrativo(string regANS, URLWebServices URLs,
            TipoGuia tipoGuia,
            long loteCod, long sequencialTransacao, long protocoloRecebimento, long? demonstrativoCod,
            string numeroGuiaPrestador, string numeroGuiaOperadora, string dataEmissao)
            : this(regANS, URLs, tipoGuia, loteCod, sequencialTransacao, protocoloRecebimento, demonstrativoCod)
        {
            this.tipo_node = node_type.guiaSolicitacao;

            this.numeroGuiaPrestador = numeroGuiaPrestador;
            this.numeroGuiaOperadora = numeroGuiaOperadora;
            this.dataEmissao = dataEmissao;
        }
    }

    /// <summary>
    /// Dados essenciais do Procedimento
    /// </summary>
    public class Procedimento
    {
        public object procedimento;
        public int indiceGuia;
        public bool isOpm;
        public object tabelaProcedimento;

        public Procedimento()
        { }
        public Procedimento(object proc, int indGuia, bool isOPM, object tabProc)
        {
            this.procedimento = proc;
            this.indiceGuia = indGuia;
            this.isOpm = isOPM;
            this.tabelaProcedimento = tabProc;
        }
    }

    /// <summary>
    /// Dados essenciais para localização da Guia
    /// </summary>
    public class GuiaPath
    {
        private string guiaPath;
        public string FilePath
        {
            get { return guiaPath; }
        }

        private bool isExtensao;
        public bool IsExtensao
        {
            get { return isExtensao; }
        }

        private int indice;
        public int Indice
        {
            get { return indice; }
        }

        public GuiaPath()
        { }
        public GuiaPath(string gp, bool isExt, int ind)
        {
            this.guiaPath = gp;
            this.isExtensao = isExt;
            this.indice = ind;
        }

    }

    /// <summary>
    /// Dados Essenciais de uma guia com Procedimentos
    /// </summary>
    public class GuiaSolicitacaoProcedimento
    {

        #region Properties

        private long codPrestador;
        public long CodPrestador
        {
            get { return codPrestador; }
            set { codPrestador = value; }
        }

        private string regANS;
        public string RegANS
        {
            get { return regANS; }
            set { regANS = value; }
        }

        private string numeroGuia;
        public string NumeroGuia
        {
            get { return numeroGuia; }
            set { numeroGuia = value; }
        }

        TipoGuia tipoSolicitacao;
        public TipoGuia TipoSolicitacao
        {
            get { return tipoSolicitacao; }
            set { tipoSolicitacao = value; }
        }

        private int countGuias = 0;
        public int CountGuias
        {
            get { return countGuias; }
        }

        private int countProcedimentos = 0;
        public int CountProcedimentos
        {
            get { return countProcedimentos; }
        }

        private int countOPMs = 0;
        public int CountOPMs
        {
            get { return countOPMs; }
        }

        private object guiaSolicProc;
        public object GuiaSolicProc
        {
            get { return guiaSolicProc; }
            set { guiaSolicProc = value; }
        }

        private List<GuiaPath> guiaPaths = new List<GuiaPath>();
        public List<GuiaPath> GuiaPaths
        {
            get { return guiaPaths; }
        }

        private List<Procedimento> listaProcedimentos = new List<Procedimento>();
        public List<Procedimento> ListaProcedimentos
        {
            get { return listaProcedimentos; }
        }

        #endregion

        /// <summary>
        /// Insere o GuiaPath de uma Guia
        /// </summary>
        /// <param name="gP">Classe Guia Path</param>
        public void insereGuiaPath(GuiaPath gP)
        {
            this.guiaPaths.Add(gP);
            countGuias++;
        }
        /// <summary>
        /// Insere o GuiaPath de uma Guia
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="isExtensao"></param>
        public void insereGuiaPath(string filePath, bool isExtensao)
        {
            GuiaPath gP = new GuiaPath(filePath, isExtensao, this.guiaPaths.Count);
            this.guiaPaths.Add(gP);
            countGuias++;
        }
        /// <summary>
        /// Insere um Procedimento da Guia
        /// </summary>
        /// <param name="proc"></param>
        /// <param name="indGuia"></param>
        /// <param name="isOPM"></param>
        /// <param name="tabProc"></param>
        public void insereProcedimento(object proc, int indGuia, bool isOPM, object tabProc)
        {
            Procedimento Proc = new Procedimento(proc, indGuia, isOPM, tabProc);
            listaProcedimentos.Add(Proc);
            if (!isOPM)
                countProcedimentos++;
            else
                countOPMs++;
        }
        /// <summary>
        /// Insere um Procedimento da Guia
        /// </summary>
        /// <param name="proc"></param>
        public void insereProcedimento(Procedimento proc)
        {
            listaProcedimentos.Add(proc);
            if (!proc.isOpm)
                countProcedimentos++;
            else
                countOPMs++;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns>Array da Lista de OPMs da Guia Toda</returns>
        public List<object> OPMToArray()
        {
            List<object> ListOPM = new List<object>();
            foreach (Procedimento opm in this.listaProcedimentos)
            {
                if (opm.isOpm)
                {
                    ListOPM.Add(opm.procedimento);
                }
            }
            return ListOPM;
        }

        public List<object> ProcedimentoToArray()
        {
            List<object> ListProcedimento = new List<object>();
            foreach (Procedimento procedimento in this.listaProcedimentos)
            {
                if (!procedimento.isOpm)
                {
                    ListProcedimento.Add(procedimento.procedimento);
                }
            }
            return ListProcedimento;
        }

        public List<object> OPMToArrayOfGuia(int indice)
        {
            List<object> ArrayOPM = new List<object>();
            foreach (Procedimento opm in this.listaProcedimentos)
            {
                if ((opm.isOpm) && (opm.indiceGuia == indice))
                    ArrayOPM.Add(opm.procedimento);
            }
            return ArrayOPM;
        }

        public List<object> ProcedimentoToArrayOfGuia(int indice)
        {
            List<object> ArrayProcedimento = new List<object>();
            foreach (Procedimento proc in this.listaProcedimentos)
            {
                if ((!proc.isOpm) && (proc.indiceGuia == indice))
                    ArrayProcedimento.Add(proc.procedimento);
            }
            return ArrayProcedimento;
        }

        public int CountOPMsOfGuia(int indice)
        {
            int count = 0;
            foreach (Procedimento proc in this.listaProcedimentos)
            {
                if ((proc.isOpm) && (proc.indiceGuia == indice))
                    count++;
            }
            return count;
        }

        public int CountProcedimentosOfGuia(int indice)
        {
            int count = 0;
            foreach (Procedimento proc in this.listaProcedimentos)
            {
                if ((!proc.isOpm) && (proc.indiceGuia == indice))
                    count++;
            }
            return count;
        }

        public GuiaSolicitacaoProcedimento()
        { }

        public GuiaSolicitacaoProcedimento(long codprestador, string regans, string numGuia, TipoGuia tipoGuia)
        {
            this.codPrestador = codprestador;
            this.regANS = regans;
            this.numeroGuia = numGuia;
            this.tipoSolicitacao = tipoGuia;
        }
    }

    public class DadosGuia
    {
        #region Properties
        private string registroANS;
        public string RegistroANS
        {
            get { return registroANS; }
            set { registroANS = value; }
        }

        private string nomeOperadora;
        public string NomeOperadora
        {
            get { return nomeOperadora; }
            set { nomeOperadora = value; }
        }

        private Image logo;
        public Image Logo
        {
            get { return logo; }
            set { logo = value; }
        }

        private string nomeContratado;
        public string NomeContratado
        {
            get { return nomeContratado; }
            set { nomeContratado = value; }
        }

        private string tipoLogradouro;
        public string TipoLogradouro
        {
            get { return tipoLogradouro; }
            set { tipoLogradouro = value; }
        }

        private string logradouro;
        public string Logradouro
        {
            get { return logradouro; }
            set { logradouro = value; }
        }

        private string numero;
        public string Numero
        {
            get { return numero; }
            set { numero = value; }
        }

        private string complemento;
        public string Complemento
        {
            get { return complemento; }
            set { complemento = value; }
        }

        private string codigoIBGEMunicipio;
        public string CodigoIBGEMunicipio
        {
            get { return codigoIBGEMunicipio; }
            set { codigoIBGEMunicipio = value; }
        }

        private string municipio;
        public string Municipio
        {
            get { return municipio; }
            set { municipio = value; }
        }
        private string codigoUF;
        public string CodigoUF
        {
            get { return codigoUF; }
            set { codigoUF = value; }
        }
        private string cep;
        public string Cep
        {
            get { return cep; }
            set { cep = value; }
        }

        private TipoPrestador tipoPrestador;
        internal TipoPrestador Tipo_Prestador
        {
            get { return tipoPrestador; }
            set { tipoPrestador = value; }
        }
        private string codigoPrestadorNaOperadora;
        public string CodigoPrestadorNaOperadora
        {
            get { return codigoPrestadorNaOperadora; }
            set { codigoPrestadorNaOperadora = value; }
        }              

        private string siglaConselho;
        public string SiglaConselho
        {
            get { return siglaConselho; }
            set { siglaConselho = value; }
        }

        private string numeroConselho;
        public string NumeroConselho
        {
            get { return numeroConselho; }
            set { numeroConselho = value; }
        }
        private string ufConselho;
        public string UFConselho
        {
            get { return ufConselho; }
            set { ufConselho = value; }
        }
        private string cpf_cnpj;
        public string CPF_CNPJ
        {
            get { return cpf_cnpj; }
            set { cpf_cnpj = value; }
        }
        private string cnes;
        public string CNES
        {
            get { return cnes; }
            set { cnes = value; }
        }
        private string cbos;
        public string CBOS
        {
            get { return cbos; }
            set { cbos = value; }
        }
        #endregion

        public DadosGuia(DataRow dr)
        {
            this.registroANS = dr["regANS"].ToString();
            this.nomeOperadora = dr["nomeOperadora"].ToString();
            if (dr["logo"] != DBNull.Value)
                if (((byte[])dr["logo"]).Count() != 0)
                {
                    Stream strImg = new MemoryStream((byte[])dr["logo"]);
                    this.logo = new Bitmap(Image.FromStream(strImg), 83, 51);
                }
            this.nomeContratado = dr["nomePrestador"].ToString();
            this.tipoLogradouro = dr["tipoLogradouro"].ToString();
            this.logradouro = dr["logradouro"].ToString();
            this.numero = dr["numero"].ToString();
            this.complemento = dr["complemento"].ToString();
            this.codigoIBGEMunicipio = dr["codIBGEMun"].ToString();
            this.municipio = dr["municipio"].ToString();
            this.codigoUF = dr["codUF"].ToString();
            this.cep = dr["CEP"].ToString();
            if (dr["IDProfissional"].ToString() != "")
            {
                this.tipoPrestador = TipoPrestador.Profissional;

                this.siglaConselho = dr["siglaConselho"].ToString();
                this.numeroConselho = dr["numeroConselho"].ToString();
                this.ufConselho = dr["ufConselho"].ToString();
                this.cbos = dr["CBOS"].ToString();
                //if (dr["codnaOperadora"].ToString() != "")
                this.codigoPrestadorNaOperadora = dr["codnaOperadora"].ToString();
                //else
                this.cpf_cnpj = dr["CPF"].ToString();
            }
            else if (dr["IDClin_Hosp"].ToString() != "")
            {
                this.tipoPrestador = TipoPrestador.Hospital_Clinica;

                this.cnes = dr["CNES"].ToString();
                //if (dr["codnaOperadora"].ToString() != "")
                this.codigoPrestadorNaOperadora = dr["codnaOperadora"].ToString();
                //else
                this.cpf_cnpj = dr["CNPJ"].ToString();
            }
        }
    }

    public class TipoGuiaCustomXML
    {
        public TipoGuia tipoGuia = new TipoGuia();
        public object customXML = new object();
    }

    public class AddValue
    {
        private string m_Display;
        private int m_Value;
        public AddValue(string Display, int Value)
        {
            m_Display = Display;
            m_Value = Value;
        }
        public string Display
        {
            get { return m_Display; }
        }
        public int Value
        {
            get { return m_Value; }
        }
    }

    #region Enums

    public enum TipoGuia
    {
        Consulta = 1,
        SP_SADT = 2,
        Resumo_Internação = 3,
        Honorário_Individual = 4,
        Odontologia = 5,
        Consulta_Reapresentação = 6,
        SP_SADT_Reapresentação = 7,
        Resumo_Internação_Reapresentação = 8,
        Honorário_Individual_Reapresentação = 9,
        Odontologia_Reapresentação = 10,
        Solicitação_Internação = 11,
        Solicitação_Prorrogação = 12,
        Solicitação_SADT = 13,
        Solicitação_Odontologia = 14,
        Demonstrativo_Pagamento = 15,
        Demonstrativo_Análise_Conta = 16,
        Demonstrativo_Odontologia = 17,
        Outras_Despesas = 18
    }

    //TODO: Não Precisa deste enum, é só usar o Simple Type de identificação na operadora
    public enum TipoCustomControlXmlMapping
    {
        CPF,
        CNPJ,
        CodigoPrestadorNaOperadora
    }

    public enum node_type
    {
        operadora,
        tipo_lote,
        tipo_solicitacao,
        lote,
        guiaFaturamento,
        guiaSolicitacao,
        guiaExtensao
    }

    public enum statusRecebimento
    {
        Recebido = 1,
        Em_analise = 2,
        Liberado_para_pagamento = 3,
        Encerrado_sem_pagamento = 4,
        Analisado_e_aguardando_liberacao_para_o_pagamento = 5,
        Pagamento_efetuado = 6,
        Protocolo_nao_localizado = 7,
        Lote_nao_enviado = 8,
        Autorizado = 9,
        Negado = 10
    }

    public enum tipoTransacao
    {
        ENVIO_LOTE_GUIAS = 1,
        SOLIC_DEMONSTRATIVO_RETORNO = 2,
        SOLIC_STATUS_PROTOCOLO = 3,
        SOLICITACAO_PROCEDIMENTOS = 4,
        PROTOCOLO_RECEBIMENTO = 5,
        SITUACAO_PROTOCOLO = 6,
        RESPOSTA_SOLICITACAO = 7,
        DEMONSTRATIVO_PAGAMENTO = 8,
        DEMONSTRATIVO_ANALISE_CONTA = 9,
        DEMONSTRATIVO_ODONTOLOGIA = 10,
        CANCELAMENTO_GUIA_RECIBO = 11,
        RE_APRESENTACAO_GUIA = 12,
        CANCELA_GUIA = 13,
        VERIFICA_ELEGIBILIDADE = 14,
        SITUACAO_ELEGIBILIDADE = 15,
        AUTORIZACAO_ODONTOLOGIA = 16,
        SOLICITA_STATUS_AUTORIZACAO = 17,
        STATUS_AUTORIZACAO = 18,
        GERA_XML_ENVIO_LOTE_GUIAS = 19,
        GERA_XML_SOLIC_DEMONSTRATIVO_RETORNO = 20,
        GERA_XML_SOLIC_STATUS_PROTOCOLO = 21,
        GERA_XML_SOLICITACAO_PROCEDIMENTOS = 22,
        GERA_XML_PROTOCOLO_RECEBIMENTO = 23,
        GERA_XML_SITUACAO_PROTOCOLO = 24,
        GERA_XML_RESPOSTA_SOLICITACAO = 25,
        GERA_XML_DEMONSTRATIVO_PAGAMENTO = 26,
        GERA_XML_DEMONSTRATIVO_ANALISE_CONTA = 27,
        GERA_XML_DEMONSTRATIVO_ODONTOLOGIA = 28,
        GERA_XML_CANCELAMENTO_GUIA_RECIBO = 29,
        GERA_XML_RE_APRESENTACAO_GUIA = 30,
        GERA_XML_CANCELA_GUIA = 31,
        GERA_XML_VERIFICA_ELEGIBILIDADE = 32,
        GERA_XML_SITUACAO_ELEGIBILIDADE = 33,
        GERA_XML_AUTORIZACAO_ODONTOLOGIA = 34,
        GERA_XML_SOLICITA_STATUS_AUTORIZACAO = 35,
        GERA_XML_STATUS_AUTORIZACAO = 36
    }

    public enum TipoPrestador
    {
        Profissional,
        Hospital_Clinica
    }

    public enum TipoProfissional
    {
        ProfissionalSolicitante,
        ProfissionalExecutante,
        ProfissionalSolicitanteExecutante
    }

    public enum TipoCTProcedimento
    { 
        ct_procedimentoRealizadoEquipe,
        ct_procedimentosRealizados,
        ct_procedimentoRevisao,
        ct_procedimentosSolicitados,
        ct_procedimentoOdontologia,
        ct_procedimentoOdontoSolicitacao
    }

    public enum TipoCTOPM
    { 
        ct_OPMUtilizada,
        ct_OPMUtilizadaRevisao,
        ct_OPMSolicitadas
    }

    #endregion

    

}
